/*
 * Copyright (c) 2009, David A. Freels Sr.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification, are permitted provided that
 * the following conditions are met:
 *
 *     * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
 *     * Neither the name of the <ORGANIZATION> nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

package net.whippetcode.plugins.intellij.hudson.ui.job;

import net.whippetcode.plugins.intellij.hudson.domain.job.Workspace;
import net.whippetcode.plugins.intellij.hudson.ui.GuiUtil;
import net.whippetcode.plugins.intellij.hudson.ui.IViewListener;

import javax.swing.*;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.TreePath;
import javax.swing.tree.TreeSelectionModel;
import java.awt.*;
import java.awt.event.*;

/**
 * This class represents the view for the Job control.
 *
 * @author David A. Freels Sr.
 */
public class HudsonJobView extends JPanel implements ActionListener, TreeSelectionListener
{
	public static final String OPEN = "OPEN";
	public static final String RUN = "RUN";
	public static final String TESTS = "TESTS";
	public static final String VIEW = "VIEW";
	public static final String REFRESH = "REFRESH";
	public static final String COMPARE = "COMPARE";

	private JButton browseButton;
	private JButton runButton;
	private JButton testButton;
	private JButton viewButton;
	private JPopupMenu compareMenu;
	private IViewListener listener;
	private TreePath workspace;
	private JMenuItem compareMenuItem;

	/**
	 * Creates a new instance of the view.
	 *
	 * @param jobTree	The tree that will display the Jobs.
	 * @param listener The listener that will handle the view events.
	 */
	public HudsonJobView(final JTree jobTree, IViewListener listener)
	{
		this.listener = listener;
		if (listener == null)
		{
			throw new IllegalArgumentException("IViewListener can not be null!");
		}

		JScrollPane jobScrollPane = new JScrollPane(jobTree, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);

		setLayout(new BorderLayout());
		add(createJPanel(), BorderLayout.NORTH);
		add(jobScrollPane, BorderLayout.CENTER);

		jobTree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
		jobTree.addTreeSelectionListener(this);
		jobTree.addMouseListener(new MouseListener()
		{
			public void mouseClicked(MouseEvent mouseEvent)
			{
			}

			public void mousePressed(MouseEvent mouseEvent)
			{
				maybeShowPopup(mouseEvent);
			}

			public void mouseReleased(MouseEvent mouseEvent)
			{
				maybeShowPopup(mouseEvent);
			}

			public void mouseEntered(MouseEvent mouseEvent)
			{
			}

			public void mouseExited(MouseEvent mouseEvent)
			{
			}

			private void maybeShowPopup(MouseEvent e)
			{
				if (e.isPopupTrigger())
				{
					if (!(jobTree.getPathForRow(jobTree.getRowForLocation(e.getX(), e.getY())) == null))
					{
						if (jobTree.getPathForLocation(e.getX(), e.getY()).getLastPathComponent() instanceof Workspace)
						{
							workspace = jobTree.getPathForLocation(e.getX(), e.getY());
							compareMenuItem.setEnabled(!((Workspace) workspace.getLastPathComponent()).isDirectory());
							compareMenu.show(e.getComponent(), e.getX(), e.getY());
						}
						else
						{
							workspace = null;
						}
					}
					else
					{
						workspace = null;
					}
				}
			}
		});
	}

	private JPanel createJPanel()
	{
		browseButton = GuiUtil.createButton("Open in browser", GuiUtil.createIcon("/net/whippetcode/plugins/intellij/hudson/images/web_browser(16x16).png"), this, OPEN);
		browseButton.setEnabled(false);

		runButton = GuiUtil.createButton("Run Job", GuiUtil.createIcon("/net/whippetcode/plugins/intellij/hudson/images/play(16x16).png"), this, RUN);
		runButton.setEnabled(false);

		testButton = GuiUtil.createButton("Show Tests", GuiUtil.createIcon("/net/whippetcode/plugins/intellij/hudson/images/clipboard(16x16).gif"), this, TESTS);
		testButton.setEnabled(false);

		viewButton = GuiUtil.createButton("Go to view", GuiUtil.createIcon("/net/whippetcode/plugins/intellij/hudson/images/coherence(16x16).png"), this, VIEW);
		viewButton.setEnabled(false);

		JButton refreshButton = GuiUtil.createButton("Refresh status", GuiUtil.createIcon("/net/whippetcode/plugins/intellij/hudson/images/Transfer(small).png"), this, REFRESH);

		compareMenu = new JPopupMenu();

		compareMenuItem = new JMenuItem("Compare to local");
		compareMenuItem.setActionCommand(COMPARE);
		compareMenuItem.addActionListener(this);

		compareMenu.add(compareMenuItem);

		JPanel panel = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0));

		JToolBar toolbar = new JToolBar();
    toolbar.setFloatable(false);

		toolbar.add(browseButton);
		addSpacing(toolbar);
		toolbar.add(viewButton);
		toolbar.addSeparator();
		addSpacing(toolbar);
		toolbar.add(runButton);
		addSpacing(toolbar);
		toolbar.add(testButton);
		addSpacing(toolbar);
		toolbar.addSeparator();
		toolbar.add(refreshButton);

		panel.add(toolbar);
		return panel;
	}

	private void addSpacing(Container container)
	{
		if (GuiUtil.isMacOS())
		{
			container.add(Box.createHorizontalStrut(2));
		}
	}

	public void actionPerformed(ActionEvent actionEvent)
	{
		WorkspaceEvent event = new WorkspaceEvent(actionEvent);
		event.setPath(workspace);
		if(event.getPath() != null)
		{
			listener.handleEvent(event);
			workspace = null;
		} else
		{
			listener.handleEvent(actionEvent);
		}

	}

	public void valueChanged(TreeSelectionEvent treeSelectionEvent)
	{
		listener.handleEvent(treeSelectionEvent);
	}

	/**
	 * Sets the enabled state of the run button.
	 *
	 * @param enabled The enabled state of the run button.
	 */
	void setRunEnabled(boolean enabled)
	{
		runButton.setEnabled(enabled);
	}

	/**
	 * Sets the enabled state of the open button.
	 *
	 * @param enabled The enabled state of the open button.
	 */
	void setOpenEnabled(boolean enabled)
	{
		browseButton.setEnabled(enabled);
	}

	/**
	 * Sets the enabled state of the test button.
	 *
	 * @param enabled The enabled state of the test button.
	 */
	void setTestEnabled(boolean enabled)
	{
		testButton.setEnabled(enabled);
	}

	/**
	 * Sets the enabled state of the view button.
	 *
	 * @param enabled The enabled state of the view button.
	 */
	void setViewEnabled(boolean enabled)
	{
		viewButton.setEnabled(enabled);
	}
}

